/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.jpa.controllers;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import co.com.entities.Unidaddistancia;
import co.com.entities.Asteroide;
import co.com.entities.ClasificacionAsteroide;
import co.com.jpa.controllers.exceptions.NonexistentEntityException;
import co.com.jpa.controllers.exceptions.PreexistingEntityException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author dloaiza
 */
public class ClasificacionAsteroideJpaController implements Serializable {

    public ClasificacionAsteroideJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(ClasificacionAsteroide clasificacionAsteroide) throws PreexistingEntityException, Exception {
        if (clasificacionAsteroide.getAsteroideList() == null) {
            clasificacionAsteroide.setAsteroideList(new ArrayList<Asteroide>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Unidaddistancia unidadDistancia = clasificacionAsteroide.getUnidadDistancia();
            if (unidadDistancia != null) {
                unidadDistancia = em.getReference(unidadDistancia.getClass(), unidadDistancia.getCdunidad());
                clasificacionAsteroide.setUnidadDistancia(unidadDistancia);
            }
            List<Asteroide> attachedAsteroideList = new ArrayList<Asteroide>();
            for (Asteroide asteroideListAsteroideToAttach : clasificacionAsteroide.getAsteroideList()) {
                asteroideListAsteroideToAttach = em.getReference(asteroideListAsteroideToAttach.getClass(), asteroideListAsteroideToAttach.getNmidAsteroide());
                attachedAsteroideList.add(asteroideListAsteroideToAttach);
            }
            clasificacionAsteroide.setAsteroideList(attachedAsteroideList);
            em.persist(clasificacionAsteroide);
            if (unidadDistancia != null) {
                unidadDistancia.getClasificacionAsteroideList().add(clasificacionAsteroide);
                unidadDistancia = em.merge(unidadDistancia);
            }
            for (Asteroide asteroideListAsteroide : clasificacionAsteroide.getAsteroideList()) {
                ClasificacionAsteroide oldNmidClasificacionOfAsteroideListAsteroide = asteroideListAsteroide.getNmidClasificacion();
                asteroideListAsteroide.setNmidClasificacion(clasificacionAsteroide);
                asteroideListAsteroide = em.merge(asteroideListAsteroide);
                if (oldNmidClasificacionOfAsteroideListAsteroide != null) {
                    oldNmidClasificacionOfAsteroideListAsteroide.getAsteroideList().remove(asteroideListAsteroide);
                    oldNmidClasificacionOfAsteroideListAsteroide = em.merge(oldNmidClasificacionOfAsteroideListAsteroide);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findClasificacionAsteroide(clasificacionAsteroide.getNmidClasificacion()) != null) {
                throw new PreexistingEntityException("ClasificacionAsteroide " + clasificacionAsteroide + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(ClasificacionAsteroide clasificacionAsteroide) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClasificacionAsteroide persistentClasificacionAsteroide = em.find(ClasificacionAsteroide.class, clasificacionAsteroide.getNmidClasificacion());
            Unidaddistancia unidadDistanciaOld = persistentClasificacionAsteroide.getUnidadDistancia();
            Unidaddistancia unidadDistanciaNew = clasificacionAsteroide.getUnidadDistancia();
            List<Asteroide> asteroideListOld = persistentClasificacionAsteroide.getAsteroideList();
            List<Asteroide> asteroideListNew = clasificacionAsteroide.getAsteroideList();
            if (unidadDistanciaNew != null) {
                unidadDistanciaNew = em.getReference(unidadDistanciaNew.getClass(), unidadDistanciaNew.getCdunidad());
                clasificacionAsteroide.setUnidadDistancia(unidadDistanciaNew);
            }
            List<Asteroide> attachedAsteroideListNew = new ArrayList<Asteroide>();
            for (Asteroide asteroideListNewAsteroideToAttach : asteroideListNew) {
                asteroideListNewAsteroideToAttach = em.getReference(asteroideListNewAsteroideToAttach.getClass(), asteroideListNewAsteroideToAttach.getNmidAsteroide());
                attachedAsteroideListNew.add(asteroideListNewAsteroideToAttach);
            }
            asteroideListNew = attachedAsteroideListNew;
            clasificacionAsteroide.setAsteroideList(asteroideListNew);
            clasificacionAsteroide = em.merge(clasificacionAsteroide);
            if (unidadDistanciaOld != null && !unidadDistanciaOld.equals(unidadDistanciaNew)) {
                unidadDistanciaOld.getClasificacionAsteroideList().remove(clasificacionAsteroide);
                unidadDistanciaOld = em.merge(unidadDistanciaOld);
            }
            if (unidadDistanciaNew != null && !unidadDistanciaNew.equals(unidadDistanciaOld)) {
                unidadDistanciaNew.getClasificacionAsteroideList().add(clasificacionAsteroide);
                unidadDistanciaNew = em.merge(unidadDistanciaNew);
            }
            for (Asteroide asteroideListOldAsteroide : asteroideListOld) {
                if (!asteroideListNew.contains(asteroideListOldAsteroide)) {
                    asteroideListOldAsteroide.setNmidClasificacion(null);
                    asteroideListOldAsteroide = em.merge(asteroideListOldAsteroide);
                }
            }
            for (Asteroide asteroideListNewAsteroide : asteroideListNew) {
                if (!asteroideListOld.contains(asteroideListNewAsteroide)) {
                    ClasificacionAsteroide oldNmidClasificacionOfAsteroideListNewAsteroide = asteroideListNewAsteroide.getNmidClasificacion();
                    asteroideListNewAsteroide.setNmidClasificacion(clasificacionAsteroide);
                    asteroideListNewAsteroide = em.merge(asteroideListNewAsteroide);
                    if (oldNmidClasificacionOfAsteroideListNewAsteroide != null && !oldNmidClasificacionOfAsteroideListNewAsteroide.equals(clasificacionAsteroide)) {
                        oldNmidClasificacionOfAsteroideListNewAsteroide.getAsteroideList().remove(asteroideListNewAsteroide);
                        oldNmidClasificacionOfAsteroideListNewAsteroide = em.merge(oldNmidClasificacionOfAsteroideListNewAsteroide);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                BigDecimal id = clasificacionAsteroide.getNmidClasificacion();
                if (findClasificacionAsteroide(id) == null) {
                    throw new NonexistentEntityException("The clasificacionAsteroide with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(BigDecimal id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClasificacionAsteroide clasificacionAsteroide;
            try {
                clasificacionAsteroide = em.getReference(ClasificacionAsteroide.class, id);
                clasificacionAsteroide.getNmidClasificacion();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The clasificacionAsteroide with id " + id + " no longer exists.", enfe);
            }
            Unidaddistancia unidadDistancia = clasificacionAsteroide.getUnidadDistancia();
            if (unidadDistancia != null) {
                unidadDistancia.getClasificacionAsteroideList().remove(clasificacionAsteroide);
                unidadDistancia = em.merge(unidadDistancia);
            }
            List<Asteroide> asteroideList = clasificacionAsteroide.getAsteroideList();
            for (Asteroide asteroideListAsteroide : asteroideList) {
                asteroideListAsteroide.setNmidClasificacion(null);
                asteroideListAsteroide = em.merge(asteroideListAsteroide);
            }
            em.remove(clasificacionAsteroide);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<ClasificacionAsteroide> findClasificacionAsteroideEntities() {
        return findClasificacionAsteroideEntities(true, -1, -1);
    }

    public List<ClasificacionAsteroide> findClasificacionAsteroideEntities(int maxResults, int firstResult) {
        return findClasificacionAsteroideEntities(false, maxResults, firstResult);
    }

    private List<ClasificacionAsteroide> findClasificacionAsteroideEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(ClasificacionAsteroide.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public ClasificacionAsteroide findClasificacionAsteroide(BigDecimal id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(ClasificacionAsteroide.class, id);
        } finally {
            em.close();
        }
    }

    public int getClasificacionAsteroideCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<ClasificacionAsteroide> rt = cq.from(ClasificacionAsteroide.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
